package com.cloud.manage.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 配置@Async线程池
 * @author why
 * @Description: 实现AsyncConfigurer自定义异常线程池，包含异常处理
 */
@Slf4j
@Service
@Configuration
public class AsyncConfig implements AsyncConfigurer {
    @Bean
    public ExecutorService executorService() {
        // Define a fixed thread pool with a number of threads (you can adjust the size based on your requirements)
        return Executors.newFixedThreadPool(200); // Example: 10 threads in the pool
    }
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
        threadPool.setCorePoolSize(100);
        threadPool.setMaxPoolSize(2000);
        threadPool.setQueueCapacity(1024);
        threadPool.setWaitForTasksToCompleteOnShutdown(true);
        threadPool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        threadPool.setAwaitTerminationSeconds(60 * 15);

        //时间戳方式
//        threadPool.setThreadNamePrefix("Async-");
        //任务id方式
        threadPool.setThreadNamePrefix("Async-" );
        threadPool.initialize();
        return threadPool;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new MyAsyncExceptionHandler();
    }

    /**
     * 自定义异常处理类
     * @author hry
     *
     */
    class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

        @Override
        public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
            log.error("Method name - " + method.getName() + "，Exception message - " + throwable.getMessage(), throwable);
            for (Object param : obj) {
                log.error("Parameter value - " + param);
            }
        }
    }
}
